import ast

c = \
'''
def asdf():
    pass
class List(list):
    filter = lambda self, fn: List(filter(fn, self))
    def flat(self):
        new_list = List()
        for x in self:
            new_list.extend(x)
        return new_list
    def forEach(self, fn):
        for x in self:
            fn(x)
    map = lambda self, fn: List(map(fn, self))
    def __each_list(lis, keys, keys_len, index=0):
        key = keys[index]
        result = lis.__getitem__(key)
        new_index = index + 1
        if new_index < keys_len:
            result = list(map(lambda l: List.__each_list(l, keys, keys_len, new_index), result))
        return result
    def __getitem__(self, key):
        print(type(List.__each_list))
        return List.__each_list(super(), key, len(key)) if isinstance(key, tuple) else super().__getitem__(key)
class Tuple(tuple):
    def forEach(self, fn):
        for x in self:
            fn(x)
class Set(set):
    def forEach(self, fn):
        for x in self:
            fn(x)
class Dict(dict):
    def forEach(self, fn):
        for k, v in self.items():
            fn(k, v)

t = [1, 2, 3, 6, 4, 5]
t = [t, t, t]
print(t)
print(t[:, 2])
print(t.flat().map(lambda x: x*2))

'''

class transformer(ast.NodeTransformer):
    def visit_List(self, node):
        return ast.Call(func=ast.Name(id='List', ctx=ast.Load()), args=[node], keywords=[]) if isinstance(node.ctx, ast.Load) else node
    def visit_ListComp(self, node):
        return ast.Call(func=ast.Name(id='List', ctx=ast.Load()), args=[node], keywords=[])
    def visit_Tuple(self, node):
        return ast.Call(func=ast.Name(id='Tuple', ctx=ast.Load()), args=[node], keywords=[]) if isinstance(node.ctx, ast.Load) else node
    def visit_Set(self, node):
        return ast.Call(func=ast.Name(id='Set', ctx=ast.Load()), args=[node], keywords=[])
    def visit_SetComp(self, node):
        return ast.Call(func=ast.Name(id='Set', ctx=ast.Load()), args=[node], keywords=[])
    def visit_Dict(self, node):
        return ast.Call(func=ast.Name(id='Dict', ctx=ast.Load()), args=[node], keywords=[])
    def visit_DictComp(self, node):
        return ast.Call(func=ast.Name(id='Dict', ctx=ast.Load()), args=[node], keywords=[])

print(ast.dump(ast.parse(c), indent=2))

tf = transformer()
tc = tf.visit(ast.parse(c))
tc = ast.fix_missing_locations(tc)
cc = compile(tc, filename="<ast>", mode="exec")
exec(cc)











